﻿package org.nickro.project.utils {
    import flash.display.Sprite;
    import flash.utils.getDefinitionByName;
	import flash.utils.getQualifiedClassName;
	
    public class Objects {

        public function Objects(){
            super();
            throw (new Error("ERROR org.nickro.project.utils.Objects constructor: Class never intended to be instantiated"));
        }
		/**
		 * 
		 * @param	className		类名
		 * @param	containerSWF	包含类实例的SWF文件
		 * @return  类
		 */
        public static function referenceToClass(className:String, containerSWF:Sprite=null):Class{
            var classRef:Class;
            if ((containerSWF is Sprite)){
                classRef = (containerSWF.loaderInfo.applicationDomain.getDefinition(className) as Class);
            } else {
                classRef = (getDefinitionByName(className) as Class);
            };
            return (classRef);
        }
		/**
		 * 
		 * @param	className		类名
		 * @param	containerSWF	包含类实例的SWF文件
		 * @return	实例类
		 */
        public static function instanceOfClass(className:String, containerSWF:Sprite=null):void{
            var classRef:Class;
            if ((containerSWF is Sprite)){
                classRef = (containerSWF.loaderInfo.applicationDomain.getDefinition(className) as Class);
            } else {
                classRef = (getDefinitionByName(className) as Class);
            };
            return (new (classRef));
        }
		/**
		 * 
		 * @param	obj			对象
		 * @param	title_str	
		 * @param	indent		属性之间的缩进量(空格)
		 */
        public static function traceObject(obj:Object, title_str:String="obj", indent:Number=0):void{
            var propValue:Object;
            var propType:String;
            var propName:String;
            var indent_str:String = "";
            var i:int;
            while (i < indent) {
                indent_str = (indent_str + " ");
                i++;
            };
            trace(((indent_str + title_str) + "[object]"));
            for (propName in obj) {
                propValue = obj[propName];
                propType = typeof(propValue);
                switch (propType){
                    case "object":
                        traceObject(propValue, ((title_str + ".") + propName), (indent + 2));
                        break;
                    case "function":
                        break;
                    default:
                        trace(indent_str + "  " + title_str + "." + propName + "=" + propValue)+ "[" + propType + "]");
                };
            };
        }
		/**
		 * 
		 * @param	obj			对象
		 * @param	recurseFlag	递归与否
		 * @param	indent		属性之间的缩进量(空格)
		 * @return
		 */
        public static function propsToString(obj:Object, recurseFlag:Boolean=true, indent:Number=0):String{
            var propValue:Object;
            var propType:String;
            var propClass:String;
            var propName:String;
            var indent_str:String = "";
            var i:int;
            while (i < indent) {
                indent_str = (indent_str + " ");
                i++;
            };
            var result_str:String = "";
            for (propName in obj) {
                propValue = obj[propName];
                propType = typeof(propValue);
                if (propType != "function"){
                    propClass = (("[" + getQualifiedClassName(propValue)) + "]");
                    if (result_str.length > 0){
                        result_str = (result_str + "\n");
                    };
                };
                switch (propType){
                    case "function":
                        break;
                    case "object":
                        result_str = (result_str + ((indent_str + propName) + propClass));
                        if (recurseFlag){
                            result_str = (result_str + ("\n" + propsToString(propValue, recurseFlag, (indent + 2))));
                        };
                        break;
                    default:
                        result_str = (result_str + ((((indent_str + propName) + "=") + propValue) + propClass));
                };
            };
            return (result_str);
        }
		/**
		 * 
		 * @param	instance		实例
		 * @param	containerSWF	
		 * @return	返回实例对象的原始类
		 */
        public static function getClassOfInstance(instance, containerSWF:Sprite=null):Class{
            var classRef:Class;
            var className:String = getQualifiedClassName(instance);
            if ((containerSWF is Sprite)){
                classRef = (containerSWF.loaderInfo.applicationDomain.getDefinition(className) as Class);
            } else {
                classRef = (getDefinitionByName(className) as Class);
            };
            return (classRef);
        }
		/**
		 * 
		 * @param	obj
		 * @param	name
		 * @param	argArray
		 */
        public static function applyMethod(obj, name:String, argArray:Array=null){
            var args:Array;
            if ((obj is Proxy)){
                args = [name];
                if (!(argArray == null) && argArray.length > 0){
                    args["push"].apply(args, argArray);
                };
                return (Proxy(obj).flash_proxy::callProperty.apply(obj, args));
                //unresolved jump
            };
            return (obj[name].apply(obj, argArray));
        }

    }
}